from market.models import Asset, Player, Strategy
from market.view import View
from market.mathView import viewAdd, viewMul
from market.mathView import view2vec
from market.math import isARepartition
from market.strategyAndFundHelper import isFixedStrat


# helper func
def _add(x,y):
        return x+y

        
# this class contains all the info of the market
# this object is the one given to the view that will display it
class MarketData:


        ###########################################################################################
	#
	#          PRIVATE
	#
        ###########################################################################################

	
        ###########################################################################################
        # constructor
	def __init__( self, betroom ):
                self._betroom = betroom
		self._market = self._getMarketFromDB()
		self._marketView = self._calculateMarketView()
		self.assets = Asset.objects.filter(isAvailableForStandardStrategy=True,betroom = betroom)



        #########################################################################################################################
        #The market price of an asset is:
	def _calculateMarketView(self):
		v = View()
		for (fundView,numberAsset) in self._market:
			v = viewAdd(v, fundView,self._betroom)
		# we need to convert to a float to make the division
		return viewMul(v, 1 / float(len(Player.objects.filter(mainStrategy__betroom = self._betroom))), self._betroom)
	

	###########################################################################################
	# the market data are recorded in that object using a list [(fundView, mtm)...]
	def _getMarketFromDB(self):
		lTmp = []
		for p in Player.objects.filter(mainStrategy__betroom = self._betroom):
			v = View()
			v.setViewFromStrategy(p.mainStrategy)
			lTmp.append((v,0))
		return lTmp

	###########################################################################################
        # returns the view value, should not be used out side the class
	def _getViewMtM(self, view ):
		return reduce(_add,[ a[1] * self.getAssetPrice( a[0] ) for a in view.viewOnAssets ],0)


        ###########################################################################################
	#
	#          PUBLIC
	#
        ###########################################################################################

        ###########################################################################################
	# returns the view of the market. a view is the vector form of a strategy.
	def getBetroom(self):
		return self._betroom
	

        ###########################################################################################
	# returns the view of the market. a view is the vector form of a strategy.
	def getMarketView(self):
		return self._marketView



        ###########################################################################################
	# returns the asset event expectation in the market.
	def getMarketExpectation(self, asset):
                if asset.fixValue != -1 :
                        return asset.fixValue
		return self._marketView.getViewOnAsset( asset )


        ###########################################################################################
	# returns the asset event expectation in the market.
	def getAssetPrice(self, asset):
                if asset.fixValue != -1 :
                        return asset.fixValue
		return 100 * self.getMarketExpectation( asset ) * asset.valueMultiplier
        

        ###########################################################################################
        # returns the MtM of the strategy wich is invested like the market.
	def getMktStratMtM( self ):
                return self._getViewMtM( self._marketView )
                

        ###########################################################################################
        # returns the strategy MtM of the player. 
	def getStrategyMtM(self, strategy ):
		tmp = isFixedStrat( strategy )	
                if tmp[0]:
                        return tmp[1]
                else:
                        v = View()
                        v.setViewFromStrategy(strategy)
                        return self._getViewMtM( v )


	
	
